//package com.pug.user.filters;
//
//import cn.hutool.core.text.CharSequenceUtil;
//import cn.hutool.core.util.StrUtil;
//import com.google.common.collect.Lists;
//import com.google.common.collect.Maps;
//import com.google.common.net.HttpHeaders;
//import com.pug.user.dto.AccessLog1ReqDTO;
//import com.pug.user.service.impl.AccessLog1ServiceImpl;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.BeanFactory;
//import org.springframework.http.HttpMethod;
//import org.springframework.http.MediaType;
//import org.springframework.util.CollectionUtils;
//import org.springframework.web.context.support.WebApplicationContextUtils;
//import org.springframework.web.filter.OncePerRequestFilter;
//import org.springframework.web.util.ContentCachingRequestWrapper;
//import org.springframework.web.util.ContentCachingResponseWrapper;
//import org.springframework.web.util.WebUtils;
//
//import javax.servlet.FilterChain;
//import javax.servlet.ServletException;
//import javax.servlet.annotation.WebFilter;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.io.UnsupportedEncodingException;
//import java.net.URLDecoder;
//import java.nio.charset.StandardCharsets;
//import java.util.Enumeration;
//import java.util.List;
//import java.util.Map;
//
///**
// * @author RenGaoshuai
// * @date 2023/5/9 15:02
// * @description 统一请求过滤器
// */
//@WebFilter(filterName = "AccessLog1Filter", urlPatterns = "/*")
//@Slf4j
//public class AccessLog1Filter extends OncePerRequestFilter {
//
//    private static final List<String> DEFAULT_DOWNLOAD_CONTENT_TYPE = Lists.newArrayList(
//            "application/vnd.ms-excel",//.xls
//            "application/msexcel",//.xls
//            "application/cvs",//.cvs
//            MediaType.APPLICATION_OCTET_STREAM_VALUE,//.*（ 二进制流，不知道下载文件类型）
//            "application/x-xls",//.xls
//            "application/msword",//.doc
//            MediaType.TEXT_PLAIN_VALUE,//.txt
//            "application/x-gzip"//.gz
//    );
//
//
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        //不包含api的直接放行（目前只针对华润）
////        if (!request.getRequestURI().contains("/api")) {
////            filterChain.doFilter(request, response);
////            return;
////        }
//
//
//        //请求方式
//        final String requestMethod = request.getMethod();
//        final boolean shouldWrapMethod = CharSequenceUtil.equalsIgnoreCase(requestMethod, HttpMethod.PUT.name())
//                || CharSequenceUtil.equalsIgnoreCase(requestMethod, HttpMethod.POST.name());
//
//        //是否为异步执行
//        final boolean isFirstRequest = !isAsyncDispatch(request);
//
//        //是否包装请求
//        final boolean shouldWrapRequest = isFirstRequest && !(request instanceof ContentCachingRequestWrapper) && shouldWrapMethod;
//        final HttpServletRequest requestToUse = shouldWrapRequest ? new ContentCachingRequestWrapper(request) : request;
//
//        //是否包装响应
//        final boolean shouldWrapResponse = !(response instanceof ContentCachingResponseWrapper) && shouldWrapMethod;
//        final HttpServletResponse responseToUse = shouldWrapResponse ? new ContentCachingResponseWrapper(response) : response;
//
//        final long startTime = System.currentTimeMillis();
//        try {
//            filterChain.doFilter(requestToUse, responseToUse);
//        } catch (Exception e) {
//
//            log.error("自定义过滤器异常，请检查，原因：" + e);
//            throw e;
//        } finally {
//            //保存日志
//            doSaveAccessLog1(requestToUse, responseToUse, startTime);
//        }
//
//    }
//
//    /**
//     * 获取bean
//     */
//    private <T> T getDAO(Class<T> clazz, HttpServletRequest request) {
//        BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
//        return factory.getBean(clazz);
//    }
//
//    private void doSaveAccessLog1(final HttpServletRequest request,
//                                 final HttpServletResponse response,
//                                 final long startTime) {
//        if (isAsyncStarted(request)) {
//            copyResponse(response);
//            return;
//        }
//
//        try {
//            AccessLog1ReqDTO logger = new AccessLog1ReqDTO();
//            //获取请求状态码
//            final int responseStatus = response.getStatus();
//            logger.setStatusCode(responseStatus + "");
//
//            //耗时
//            logger.setTimeConsuming(System.currentTimeMillis() - startTime);
//
//            //设置请求方法
//            logger.setMethod(request.getMethod());
//
//            String appToken = request.getHeader("appToken");
//            logger.setClientId(appToken);
//
//            //uri
//            final String requestUri = request.getRequestURI();
//            logger.setUrl(requestUri);
//
//            //请求头
//            final String requestHeaders = getRequestHeaders(request);
//            logger.setHeadersJsonData(requestHeaders);
//
//            //ip
//            final String requestIp = getRequestIp(request);
//            logger.setClientIp(requestIp);
//
//            final String requestParams = getRequestParams(request);
//            logger.setParamsJsonData(requestParams);
//
//            //入参
//            final String requestString = isUpload(request) ? StrUtil.EMPTY : getRequestString(request);
//            logger.setRequestJsonData(requestString);
//
//            //出参
//            final String responseString = isDownload(response) ? StrUtil.EMPTY : getResponseString(response);
//            logger.setResponseJsonData(responseString);
//
//            //保存日志
//            AccessLog1ServiceImpl AccessLog1Service = getDAO(AccessLog1ServiceImpl.class, request);
//            AccessLog1Service.saveLogger(logger);
//
//        } catch (Throwable e) {
//            logger.error("保存访问日志时出现异常,原因：", e);
//        } finally {
//            copyResponse(response);
//        }
//    }
//
//    /**
//     * 获取ip
//     *
//     * @param request 请求
//     * @return ip地址
//     */
//    private String getRequestIp(final HttpServletRequest request) {
//        String ip = request.getHeader("X-Real-IP");
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//            ip = request.getHeader("X-Forwarded-For");// 这是一个可以伪造的头
//            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//                ip = request.getRemoteAddr();
//            }
//        }
//        // 最后一个为RemoteAddr
//        int pos = ip.lastIndexOf(',');
//        if (pos >= 0) {
//            ip = ip.substring(pos);
//        }
//        if ("0:0:0:0:0:0:0:1".equals(ip)) {
//            ip = "127.0.0.1";
//        }
//        return ip;
//    }
//
//    /**
//     * 获取请求头
//     *
//     * @param request 请求
//     * @return 请求头
//     */
//    private String getRequestHeaders(final HttpServletRequest request) {
//        final Enumeration<String> headerNames = request.getHeaderNames();
//        final List<String> headers = Lists.newArrayList();
//        while (headerNames.hasMoreElements()) {
//            final String key = headerNames.nextElement();
//            headers.add(key + ':' + request.getHeader(key));
//        }
//        return '[' + String.join(",", headers) + ']';
//    }
//
//    /**
//     * 获取params参数
//     *
//     * @param request 请求
//     * @return
//     */
//    private String getRequestParams(final HttpServletRequest request) {
//        final Map<String, String[]> requestParams = Maps.newHashMap(request.getParameterMap());
//        final List<String> pairs = Lists.newArrayList();
//        if (!CollectionUtils.isEmpty(requestParams)) {
//            for (final Map.Entry<String, String[]> entry : requestParams.entrySet()) {
//                final String name = entry.getKey();
//                final String[] value = entry.getValue();
//                if (value == null) {
//                    pairs.add(name + "=");
//                } else {
//                    for (final String v : value) {
//                        pairs.add(name + "=" + StrUtil.trimToEmpty(v));
//
//                    }
//                }
//            }
//        }
//        String requestParamsStr = CollectionUtils.isEmpty(pairs) ? StrUtil.EMPTY : String.join("&", pairs);
//        if (CharSequenceUtil.equalsIgnoreCase(request.getContentType(), MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
//            try {
//                requestParamsStr = URLDecoder.decode(requestParamsStr, StandardCharsets.UTF_8.name());
//            } catch (UnsupportedEncodingException ignored) {
//            }
//        }
//        return requestParamsStr;
//    }
//
//    /**
//     * 获取请求参数
//     *
//     * @param request 请求
//     * @return
//     */
//    private String getRequestString(final HttpServletRequest request) {
//        final ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
//        if (wrapper != null) {
//            try {
//                final byte[] buf = wrapper.getContentAsByteArray();
//                //去除换行 回车 空格等字符
//                String s = new String(buf, wrapper.getCharacterEncoding()).replaceAll("\r|\n", "");
//                return StrUtil.cleanBlank(s);
//            } catch (UnsupportedEncodingException e) {
//                return "[UNKNOWN]";
//            }
//        }
//        return StrUtil.EMPTY;
//    }
//
//    /**
//     * 获取响应参数
//     *
//     * @param response 响应
//     * @return
//     */
//    private String getResponseString(final HttpServletResponse response) {
//        final ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
//        if (wrapper != null) {
//            try {
//                final byte[] buf = wrapper.getContentAsByteArray();
//                return new String(buf, wrapper.getCharacterEncoding()).replaceAll("\n|\r", "");
//            } catch (UnsupportedEncodingException e) {
//                return "[UNKNOWN]";
//            }
//        }
//        return StrUtil.EMPTY;
//    }
//
//    /**
//     * 复制响应
//     *
//     * @param response 响应
//     */
//    private void copyResponse(final HttpServletResponse response) {
//        final ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
//        if (wrapper != null) {
//            try {
//                wrapper.copyBodyToResponse();
//            } catch (IOException ignored) {
//            }
//        }
//    }
//
//    /**
//     * 是否是上传接口
//     *
//     * @param request 请求
//     * @return
//     */
//    private boolean isUpload(final HttpServletRequest request) {
//        final String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
//        if (StrUtil.isBlank(contentType)) {
//            return false;
//        }
//        return CharSequenceUtil.containsIgnoreCase(contentType, MediaType.MULTIPART_FORM_DATA_VALUE);
//    }
//
//
//    /**
//     * 是否是下载接口
//     *
//     * @param response 响应
//     * @return
//     */
//    private boolean isDownload(final HttpServletResponse response) {
//        final String contentType = response.getContentType();
//        if (StrUtil.isBlank(contentType)) {
//            return false;
//        }
//        return DEFAULT_DOWNLOAD_CONTENT_TYPE.stream().anyMatch(it -> CharSequenceUtil.equalsIgnoreCase(it, contentType));
//    }
//
//}
